Skip to content
This repository was archived by the owner on Nov 23, 2025. It is now read-only.

Dev ops#9

Merged
RandithaK merged 21 commits intomainfrom
devOps
Nov 7, 2025
Merged

Dev ops#9
RandithaK merged 21 commits intomainfrom
devOps

Conversation

@RandithaK
Copy link
Copy Markdown
Member

No description provided.

RandithaK and others added 20 commits November 5, 2025 21:19
…aders and update registration response status
- Use select(.kind == "Deployment") to ensure yq only modifies the Deployment
- Prevents accidental modification of Service resource in multi-document YAML
- Add debugging step to display file contents before apply
- Explicitly checkout main branch from k8s-config repo
- Matches the fix applied to API Gateway workflow
Copilot AI review requested due to automatic review settings November 7, 2025 20:46
@gitguardian
Copy link
Copy Markdown

gitguardian bot commented Nov 7, 2025

⚠️ GitGuardian has uncovered 2 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
22222403 Triggered Username Password f1d30fe test-auth-complete.sh View secret
22222402 Triggered Generic High Entropy Secret 775f9db auth-service/src/test/resources/application-test.properties View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 7, 2025

Warning

Rate limit exceeded

@RandithaK has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 11 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e4c5569 and 959fced.

📒 Files selected for processing (62)
  • .github/workflows/build.yaml (1 hunks)
  • .github/workflows/buildtest.yaml (0 hunks)
  • .github/workflows/deploy.yaml (1 hunks)
  • .idea/workspace.xml (1 hunks)
  • COMPLETE_IMPLEMENTATION_REPORT.md (1 hunks)
  • Dockerfile (1 hunks)
  • IMPLEMENTATION_SUMMARY.md (1 hunks)
  • README.md (2 hunks)
  • auth-service/.env (1 hunks)
  • auth-service/pom.xml (2 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/AuthServiceApplication.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/config/CacheConfig.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/config/CorsFilter.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/config/EmailConfig.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/config/GatewayHeaderFilter.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/config/SecurityConfig.java (3 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/controller/AuthController.java (3 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/controller/ProfilePhotoController.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/controller/UserController.java (4 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/ChangePasswordRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/CreateAdminRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/CreateEmployeeRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/ForgotPasswordRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/LoginRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/LogoutRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/RefreshTokenRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/RegisterRequest.java (3 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/ResendVerificationRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/ResetPasswordRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/ResetPasswordWithTokenRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/RoleAssignmentRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/UpdateProfileRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/UpdateUserRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/UploadProfilePhotoRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/request/VerifyEmailRequest.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/response/ApiError.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/response/ApiSuccess.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/response/LoginResponse.java (2 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/response/ProfilePhotoCacheEntry.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/response/ProfilePhotoDto.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/response/UserDto.java (2 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/dto/response/UserPreferencesDto.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/entity/RefreshToken.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/entity/User.java (4 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/entity/UserPreferences.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/entity/VerificationToken.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/exception/GlobalExceptionHandler.java (2 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/repository/LoginLockRepository.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/repository/LoginLogRepository.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/repository/RefreshTokenRepository.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/repository/UserPreferencesRepository.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/repository/VerificationTokenRepository.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/service/AuthService.java (5 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/service/EmailService.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/service/PreferencesService.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/service/ProfilePhotoService.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/service/TokenService.java (1 hunks)
  • auth-service/src/main/java/com/techtorque/auth_service/service/UserService.java (4 hunks)
  • auth-service/src/main/resources/application.properties (1 hunks)
  • auth-service/src/test/java/com/techtorque/auth_service/AuthServiceApplicationTests.java (1 hunks)
  • auth-service/src/test/resources/application-test.properties (1 hunks)
  • test-auth-complete.sh (1 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devOps

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements comprehensive authentication service enhancements including email verification, JWT refresh tokens, password reset, profile management, and user preferences. The implementation addresses all issues identified in the audit report, bringing the authentication service from 58% to 100% completion.

Key Changes:

  • Implements email verification system with token-based validation and configurable expiry
  • Adds JWT refresh token mechanism with 7-day expiry, IP/user-agent tracking, and revocation support
  • Implements password reset flow with token-based reset and email notifications
  • Adds profile management endpoints for updating user information and preferences
  • Introduces new entities: VerificationToken, RefreshToken, UserPreferences

Reviewed Changes

Copilot reviewed 61 out of 62 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
auth-service/src/main/java/com/techtorque/auth_service/AuthServiceApplication.java Adds dotenv loading for environment variables
auth-service/src/main/java/com/techtorque/auth_service/service/AuthService.java Implements email verification, refresh tokens, and password reset flows
auth-service/src/main/java/com/techtorque/auth_service/service/TokenService.java New service for managing verification and refresh tokens
auth-service/src/main/java/com/techtorque/auth_service/service/EmailService.java New service for sending verification, reset, and welcome emails
auth-service/src/main/java/com/techtorque/auth_service/service/UserService.java Adds profile update methods and cascading delete for related entities
auth-service/src/main/java/com/techtorque/auth_service/service/ProfilePhotoService.java New service for profile photo management with BLOB storage and caching
auth-service/src/main/java/com/techtorque/auth_service/service/PreferencesService.java New service for managing user notification preferences
auth-service/src/main/java/com/techtorque/auth_service/entity/* New entities for tokens, preferences, and extended User fields
auth-service/src/main/java/com/techtorque/auth_service/controller/* New endpoints for verification, refresh, profile, and preferences
auth-service/src/main/java/com/techtorque/auth_service/config/* New configuration for email, cache, CORS, and gateway headers
auth-service/pom.xml Adds dependencies for email, dotenv, and Guava caching
test-auth-complete.sh Comprehensive test script for all authentication endpoints
README.md, IMPLEMENTATION_SUMMARY.md, COMPLETE_IMPLEMENTATION_REPORT.md Updated documentation
Files not reviewed (1)
  • .idea/workspace.xml: Language not supported
Comments suppressed due to low confidence (1)

auth-service/src/main/java/com/techtorque/auth_service/entity/User.java:91


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


public static void main(String[] args) {
// Load environment variables from .env file
Dotenv dotenv = Dotenv.load();
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dotenv loading will fail in production environments where the .env file doesn't exist. Wrap this in a try-catch block or use Dotenv.configure().ignoreIfMissing().load() to prevent application startup failures when the .env file is not present.

Suggested change
Dotenv dotenv = Dotenv.load();
Dotenv dotenv = Dotenv.configure().ignoreIfMissing().load();

Copilot uses AI. Check for mistakes.

User user = User.builder()
.username(registerRequest.getUsername())
.username(registerRequest.getEmail()) // Use email as username for simplicity
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using email as username creates inconsistency since the RegisterRequest no longer has a username field, but existing code still references username. This could cause confusion when debugging user-related issues. Consider documenting this design decision clearly or adding a dedicated username field in the User entity that is displayed separately from the authentication email.

Copilot uses AI. Check for mistakes.
Comment on lines +177 to +178
.enabled(true) // Allow login without email verification
.emailVerified(false) // Track verification status separately
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting enabled=true before email verification creates a security gap. Users can log in before verifying their email, which contradicts the comment on line 177 in the registerUser method and the design intent. The login flow should check emailVerified status and reject unverified users.

Copilot uses AI. Check for mistakes.
Comment on lines +43 to +44
verificationTokenRepository.findByUserAndTokenType(user, VerificationToken.TokenType.EMAIL_VERIFICATION)
.ifPresent(verificationTokenRepository::delete);
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Deleting existing tokens before creating new ones requires two database operations. Consider using an upsert pattern or updating the existing token if present to reduce database round trips, especially under high registration load.

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +96
if (!base64Image.matches("^[A-Za-z0-9+/]*={0,2}$")) {
throw new IllegalArgumentException("Base64 string contains invalid characters");
}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex validation on line 94 could be expensive for large base64 strings (up to 5MB). Since Base64.getDecoder().decode() already throws IllegalArgumentException for invalid base64, this validation is redundant and impacts performance. Consider removing it or only using it for smaller strings.

Copilot uses AI. Check for mistakes.
@RestController
// Class-level request mapping removed — endpoints are exposed as internal paths
// @RequestMapping("/api/v1/users")
@RequestMapping("/users")
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The UserController now uses '/users' mapping but the SecurityConfig permits patterns like '/api/v1/auth/**'. This creates an inconsistent API structure where some endpoints are under /users (profile, preferences) while authentication endpoints are under /auth. Consider using a consistent base path like '/api/v1/users' or documenting the rationale for the split.

Suggested change
@RequestMapping("/users")
@RequestMapping("/api/v1/users")

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +62
package com.techtorque.auth_service.config;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
* Custom CORS filter that ensures CORS headers are added to ALL responses,
* including redirects and error responses.
*
* This filter runs at the servlet level (before Spring Security) with high priority
* to ensure CORS headers are included on every response regardless of what happens downstream.
*
* NOTE: This filter is DISABLED because CORS is handled centrally by the API Gateway.
* The API Gateway applies CORS headers to all responses, so backend services should not
* add CORS headers to avoid duplication.
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

@Value("${app.cors.allowed-origins:http://localhost:3000,http://127.0.0.1:3000}")
private String allowedOrigins;

@Override
public void init(FilterConfig filterConfig) {
// Initialize filter
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {

// CORS is handled by the API Gateway, so we skip CORS header injection here
// Just pass the request through without adding CORS headers
chain.doFilter(request, response);
}

@Override
public void destroy() {
// Cleanup
}

/**
* Check if the given origin is in the allowed list
*/
private boolean isOriginAllowed(String origin) {
String[] origins = allowedOrigins.split(",");
for (String allowed : origins) {
if (allowed.trim().equals(origin)) {
return true;
}
}
return false;
}
}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CorsFilter component is registered but does nothing (effectively a no-op). This adds unnecessary overhead to every request. If CORS is handled by the API Gateway, remove this filter component entirely rather than leaving it as dead code.

Suggested change
package com.techtorque.auth_service.config;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* Custom CORS filter that ensures CORS headers are added to ALL responses,
* including redirects and error responses.
*
* This filter runs at the servlet level (before Spring Security) with high priority
* to ensure CORS headers are included on every response regardless of what happens downstream.
*
* NOTE: This filter is DISABLED because CORS is handled centrally by the API Gateway.
* The API Gateway applies CORS headers to all responses, so backend services should not
* add CORS headers to avoid duplication.
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Value("${app.cors.allowed-origins:http://localhost:3000,http://127.0.0.1:3000}")
private String allowedOrigins;
@Override
public void init(FilterConfig filterConfig) {
// Initialize filter
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// CORS is handled by the API Gateway, so we skip CORS header injection here
// Just pass the request through without adding CORS headers
chain.doFilter(request, response);
}
@Override
public void destroy() {
// Cleanup
}
/**
* Check if the given origin is in the allowed list
*/
private boolean isOriginAllowed(String origin) {
String[] origins = allowedOrigins.split(",");
for (String allowed : origins) {
if (allowed.trim().equals(origin)) {
return true;
}
}
return false;
}
}

Copilot uses AI. Check for mistakes.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Guava version 32.1.3-jre is relatively old (released in 2023). Consider using a more recent version like 33.x to benefit from bug fixes and security patches. Check the Guava release notes for any breaking changes before upgrading.

Suggested change
<version>32.1.3-jre</version>
<version>33.1.0-jre</version>

Copilot uses AI. Check for mistakes.
Comment on lines +118 to +138
/**
* Get profile photo for any user by username
* - Returns base64 encoded image data
* - Publicly accessible for user profiles
* - Returns null if no photo exists
*
* @param username The username to get photo for
* @return ProfilePhotoDto with base64 encoded image
*/
@GetMapping("/username/{username}")
@Operation(summary = "Get user profile photo by username", description = "Retrieve profile photo for a specific user")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Photo retrieved successfully"),
@ApiResponse(responseCode = "204", description = "No photo found")
})
public ResponseEntity<?> getProfilePhotoByUsername(@PathVariable String username) {
// This would require a UserRepository method to find user by username
// For now, returning 204 (No Content) as placeholder
// TODO: Implement once UserRepository is extended
return ResponseEntity.noContent().build();
}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getProfilePhotoByUsername endpoint is documented but returns a placeholder implementation. This incomplete endpoint should either be fully implemented or removed until it can be properly developed to avoid confusion and potential misuse in production.

Suggested change
/**
* Get profile photo for any user by username
* - Returns base64 encoded image data
* - Publicly accessible for user profiles
* - Returns null if no photo exists
*
* @param username The username to get photo for
* @return ProfilePhotoDto with base64 encoded image
*/
@GetMapping("/username/{username}")
@Operation(summary = "Get user profile photo by username", description = "Retrieve profile photo for a specific user")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Photo retrieved successfully"),
@ApiResponse(responseCode = "204", description = "No photo found")
})
public ResponseEntity<?> getProfilePhotoByUsername(@PathVariable String username) {
// This would require a UserRepository method to find user by username
// For now, returning 204 (No Content) as placeholder
// TODO: Implement once UserRepository is extended
return ResponseEntity.noContent().build();
}
// /**
// * Get profile photo for any user by username
// * - Returns base64 encoded image data
// * - Publicly accessible for user profiles
// * - Returns null if no photo exists
// *
// * @param username The username to get photo for
// * @return ProfilePhotoDto with base64 encoded image
// */
// @GetMapping("/username/{username}")
// @Operation(summary = "Get user profile photo by username", description = "Retrieve profile photo for a specific user")
// @ApiResponses(value = {
// @ApiResponse(responseCode = "200", description = "Photo retrieved successfully"),
// @ApiResponse(responseCode = "204", description = "No photo found")
// })
// public ResponseEntity<?> getProfilePhotoByUsername(@PathVariable String username) {
// // This would require a UserRepository method to find user by username
// // For now, returning 204 (No Content) as placeholder
// // TODO: Implement once UserRepository is extended
// return ResponseEntity.noContent().build();
// }

Copilot uses AI. Check for mistakes.
@RandithaK RandithaK closed this Nov 7, 2025
@RandithaK RandithaK reopened this Nov 7, 2025
@RandithaK RandithaK merged commit 1ce415b into main Nov 7, 2025
8 of 9 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants